//
//  BSDSocketViewController.swift
//  MyDemoSwift
//
//  Created by 张鑫 on 2021/11/10.
//  Copyright © 2021 张鑫. All rights reserved.
//

import UIKit

class BSDSocketViewController: UIViewController {
    
    var socketid: Int32 = -1
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        layoutUI()
        
    }
    
    private lazy var createBtn: UIButton = {
        return createButton(title: "创建socket", action: #selector(initSocket))
    }()
    private lazy var connectBtn: UIButton = {
        return createButton(title: "连接socket", action: #selector(connectSocket))
    }()
    private lazy var sendBtn: UIButton = {
        return createButton(title: "发送文本", action: #selector(sendMessage))
    }()
    private lazy var receiveBtn: UIButton = {
        return createButton(title: "开始接收", action: #selector(receiveSocket))
    }()
    private lazy var sendTextField: UITextField = {
        let tf = UITextField()
        tf.translatesAutoresizingMaskIntoConstraints = false
        tf.placeholder = "aaaaaa"
        view.addSubview(tf)
        return tf
    }()
    
    func createButton(title: String, action: Selector) -> UIButton{
        let btn = UIButton(type: .custom)
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.setTitle(title, for: .normal)
        btn.setTitleColor(.black, for: .normal)
        btn.addTarget(self, action: action, for: .touchUpInside)
        btn.backgroundColor = .red
        view.addSubview(btn)
        return btn
    }
    
    func layoutUI() {
        createBtn.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 50).isActive = true
        createBtn.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
        
        connectBtn.topAnchor.constraint(equalTo: createBtn.bottomAnchor, constant: 50).isActive = true
        connectBtn.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
        
        sendBtn.topAnchor.constraint(equalTo: connectBtn.bottomAnchor, constant: 50).isActive = true
        sendBtn.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
        
        receiveBtn.topAnchor.constraint(equalTo: sendBtn.bottomAnchor, constant: 50).isActive = true
        receiveBtn.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
        
        sendTextField.bottomAnchor.constraint(equalTo: sendBtn.topAnchor).isActive = true
        sendTextField.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
    }
    
    @objc func hiddenKeyboard() {
        sendTextField.resignFirstResponder()
    }
    
    @objc func initSocket() {
        if socketid == -1 {
            socketid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
            
            //socket相关选项设置
            //允许重用本地地址和端口
            var optval = 1
            setsockopt(socketid, SOL_SOCKET, SO_REUSEADDR, &optval, socklen_t(MemoryLayout.size(ofValue: optval)))
            //            accept(<#T##Int32#>, <#T##UnsafeMutablePointer<sockaddr>!#>, <#T##UnsafeMutablePointer<socklen_t>!#>)
            //            setsockopt(<#T##Int32#>, <#T##Int32#>, <#T##Int32#>, <#T##UnsafeRawPointer!#>, <#T##socklen_t#>)
            //            select(<#T##Int32#>, <#T##UnsafeMutablePointer<fd_set>!#>, <#T##UnsafeMutablePointer<fd_set>!#>, <#T##UnsafeMutablePointer<fd_set>!#>, <#T##UnsafeMutablePointer<timeval>!#>)
            //            shutdown(<#T##Int32#>, <#T##Int32#>)
            //            close(<#T##Int32#>)
            print("socket create \(socketid)")
        } else {
            print("socket already created")
        }
    }
    
    @objc func connectSocket() {
        func ip(_ item: UInt8) -> Int8 {
            return item & 0x80 == 0x80 ? -Int8(~(item - 1) & 0x7f) : Int8(item)
        }
        
        if socketid == -1 {
            print("create socket first")
            initSocket()
        }
        //端口号12345
        //110000  00111001
        //48      57
        print(ip(177))
        var addr = sockaddr()
        addr.sa_len = __uint8_t(MemoryLayout.size(ofValue: addr))
        addr.sa_family = sa_family_t(AF_INET)
        addr.sa_data = (ip(UInt8(12345 >> 8 & 0xff)), ip(UInt8(12345 & 0xff)), //port
                        ip(10), ip(177), ip(1), ip(4), // ip addr
                        0, 0, 0, 0, 0, 0, 0, 0)
        
        _ = sockaddr_in(
            sin_len: __uint8_t(MemoryLayout.size(ofValue: sockaddr.self)),
            sin_family: sa_family_t(AF_INET),
            sin_port: 123,
            sin_addr: in_addr(s_addr: inet_addr("192.168.12.12")),
            sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)
        )
        let status = connect(socketid, &addr, socklen_t(addr.sa_len))
        print("socket connect status \(status)")
    }
    
    @objc func sendMessage() {
        let result = send(socketid, sendTextField.text, (sendTextField.text?.count ?? 0), 0)
        //send(<#T##Int32#>, <#T##UnsafeRawPointer!#>, <#T##Int#>, <#T##Int32#>)
        
        print("send socket result \(result)")
        //        sendmsg(<#T##Int32#>, <#T##UnsafePointer<msghdr>!#>, <#T##Int32#>)
        
        
    }
    
    @objc func receiveSocket() {
        
        print("ready to receive message")
        
        var msgBuffer = [UInt8](repeating: 0x0,count: 1024)
        let receiveLenth = recv(socketid, &msgBuffer, 1024, 0)
        // recv(<#T##Int32#>, <#T##UnsafeMutableRawPointer!#>, <#T##Int#>, <#T##Int32#>)
        
        print("receive socket result \(receiveLenth)")
        if receiveLenth > 0 {
            
            let receiveData = Data(bytes: msgBuffer, count: receiveLenth)
            let receiveStr = String(data: receiveData, encoding: .utf8)
            
            print("receive content \(receiveStr)")
            
            
        }
    }
    
}
